package com.second.app.spring.annoations;

import javax.security.sasl.SaslServer;
import java.io.File;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static org.springframework.cglib.proxy.Mixin.createBean;
import static org.springframework.util.ResourceUtils.getFile;


/**
 * @Author GYZ
 * @Date 2023/9/13
 * <pre>
 *
 * </pre>
 */
public class ApplicationContext {

    private final Map<String, Object> iocMap = new ConcurrentHashMap<>();


    public ApplicationContext(String packagePath) {
        scanPackage(packagePath);
    }

    public Object getBean(String beanName) {
        return iocMap.get(beanName);
    }

    private void scanPackage(String packagePath) {
        File[] classFiles = getClassFiles(packagePath);
        processClassFiles(packagePath, classFiles);
    }

    private File[] getClassFiles(String packagePath) {
        File file = getFile(packagePath);
        return filterClassFiles(packagePath, file);
    }

    private File[] filterClassFiles(String packagePath, File file) {
        return file.listFiles(item -> {
            String fileName = item.getName();
            if (item.isDirectory()) {
                scanPackage(packagePath + "." + fileName);
            } else {
                return fileName.endsWith(".class");
            }
            return false;
        });
    }

    private File getFile(String packagePath) {
        String packageDir = packagePath.replaceAll("\\.", "/");
        URL url = getClass().getClassLoader().getResource(packageDir);
        return new File(url.getFile());
    }

    private void processClassFiles(String packagePath, File[] classFiles) {
        for (File classFile : classFiles) {
            String className = classFile.getName().substring(0, classFile.getName().lastIndexOf("."));
            String fullClassName = packagePath + "." + className;
            String beanName = String.valueOf(className.charAt(0)).toLowerCase()+className.substring(1);
            createBean(beanName,fullClassName);
        }
    }

    private void createBean(String beanName,String fullClassName){
        try {
            Class<?> aClass = Class.forName(fullClassName);
            if(aClass.isAnnotationPresent(MyComponent.class)){
                System.out.println("fullClassName = "+fullClassName+" 加了MyComponent注解，准备通过反射创建实例，并放入iocMap中 ");
                Object instance = aClass.newInstance();
                iocMap.put(beanName,instance);
            }else {
                System.out.println("fullClassName = "+fullClassName+"没有加@MyCompent注解，所以不需要创建实例" );
            }
        } catch (Exception e) {
            System.out.println("通过反射创建实例报错");
        }
    }
}
